home *** CD-ROM | disk | FTP | other *** search
/ Web Designer 98 (Professional) / WebDesigner 1.0.iso / cgi2 / fly_tar.z / fly_tar / fly / fly.c next >
Encoding:
C/C++ Source or Header  |  1997-01-29  |  32.8 KB  |  1,273 lines

  1. /*******************************************************************************
  2. **  fly:  On-the-fly GIF creation utility
  3. **  Martin Gleeson, ITS, gleeson@unimelb.edu.au
  4. **  Copyright (c), The University of Melbourne, 1994,1995,1996
  5. **  Last Update: 23 Jan 1996
  6. **
  7. **  Uses the gd library by Thomas Boutell, boutell@netcom.com
  8. **  gd: Copyright 1994, Quest Protein Database Centre, Cold Spring Harbour Labs
  9. **
  10. **  Contributions from:
  11. **  John Bowe <bowe@osf.org>
  12. **     addition of better argument parsing
  13. **  Claus Hofmann <claush@ipfr.bau-verm.uni-karlsruhe.de>
  14. **     addition of 'transparent' directive.
  15. **     addtion of code to check if colour already allocated
  16. **     addition of feature to copy whole image if all coords are -1
  17. **
  18. *******************************************************************************/
  19.  
  20. char *version = "1.41";
  21. char *usage = "Usage : fly [-h] [-q] [-i inputfile] [-o outputfile.gif]";
  22.  
  23. char *help = "See <URL:http://www.unimelb.edu.au/fly/fly.html> for documentation.\n\nQuick Reference to Directives: \n\nnew\nsize x,y\nname filename.gif\n\nline   x1,y1,x2,y2,R,G,B             dline        x1,y1,x2,y2,R,G,B \nrect   x1,y1,x2,y2,R,G,B             frect        x1,y1,x2,y2,R,G,B \nsquare x,y,s,R,G,B                   fsquare      x,y,s,R,G,B \npoly   R,G,B,x1,y1...,xn,yn          fpoly        R,G,B,x1,y1...,xn,yn \nfill   x,y,R,G,B                     filltoborder x,y,R1,G1,B1,R2,B2,G2 \narc    x1,y1,w,h,start,finish,R,G,B  \ncircle x,y,d,R,G,B                   fcircle      x,y,d,R,G,B \n\nstring   R,G,B,x,y,<size>,<string> \nstringup R,G,B,x,y,<size>,<string> \n(size = tiny, small, medium, large or giant) \n\ncopy         x,y,x1,y1,x2,y2,filename.gif \ncopyresized  x1,y1,x2,y2,dx1,dy1,dx2,dy2,filename.gif \n\nsetpixel    x,y,R,G,B \ngetpixel    x,y \ntransparent R,G,B \ninterlace \n\nsetbrush    filename.gif                         killbrush \nsettile     filename.gif                         killtile \nsetstyle    R1,G1,B1,R2,G2,B2,...,Rn,Bn,Gn       killstyle \n\nsizex \nsizey \n\nend\n";
  24.  
  25. /******************************************************************************/
  26.  
  27. #include "gd.h"
  28. #include "gdfonts.h"
  29. #include "gdfontl.h"
  30. #include "gdfontmb.h"
  31. #include "gdfontt.h"
  32. #include "gdfontg.h"
  33. #include "fly.h"
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #include <errno.h>
  37. #include <string.h>
  38.  
  39. /******************************************************************************
  40. **  Internal Functions
  41. ******************************************************************************/
  42.  
  43. int         process_args(int argc, char *argv[]);
  44. int         get_token(FILE *infile);
  45. int         get_number(FILE *infile);
  46. char       *get_string(FILE *infile);
  47. void        sync_input(FILE *infile);
  48. int         get_colour(FILE *infile, gdImagePtr img);
  49. void        copy_to_gif(FILE *infile, gdImagePtr img, int resize);
  50. gdImagePtr  get_image(int type, int argc, char *argv[]);
  51. void       *my_newmem(size_t size);
  52.  
  53. /******************************************************************************
  54. **  Global Variables 
  55. ******************************************************************************/
  56.  
  57. int   finished = FALSE,
  58.           done = FALSE,
  59.          quiet = FALSE,
  60.    end_of_line = FALSE,
  61.    line_number = 0;
  62.  
  63. char     *input_file = NULL,
  64.          *output_file = NULL;
  65.  
  66. FILE     *outfile;
  67. FILE     *infile;
  68. FILE     *brushfile;
  69. FILE     *tilefile;
  70. FILE     *verbose_out;
  71.  
  72. /******************************************************************************
  73. ** Main Program
  74. ******************************************************************************/
  75.  
  76. int main(int argc, char *argv[]){
  77.     int colour, colour2, type;
  78.     int status, size, side;
  79.     int brush_on = 0, tile_on = 0, style_on = 0;
  80.     int num_entries, up = 0;
  81.     int i, n, c, x, y;
  82.     int arg[4096], style[1024];
  83.     char *s;
  84.     gdPoint points[2048];
  85.     gdImagePtr img, brush, tile;
  86.  
  87.     status = process_args(argc, argv);
  88.     if (status == FALSE) exit(0);
  89.  
  90. START:    type = get_token(infile);
  91.     while(((type == COMMENT) || (type == EMPTY) || (type == NULL)))
  92.     {
  93.         sync_input(infile);
  94.         type = get_token(infile);
  95.     }
  96.     if( type != NEW     && type != EXISTING)
  97.     {
  98.         fprintf(stderr,"Error: Must use 'new' or 'existing' directive first in input.\n");
  99.         exit(1);
  100.     }
  101.     img=get_image(type, argc, argv);
  102.  
  103.     /* while more lines to process */
  104.     do{
  105.         type = get_token(infile);
  106.         switch(type){
  107.  
  108.         case LINE:      /*      gdImageLine()           */
  109.             for(i=1;i<=4;i++)
  110.             {
  111.                 arg[i]=get_number(infile);
  112.             }
  113.             if (!quiet) fprintf(verbose_out,"## Line ## drawn from %d,%d to %d,%d. (",
  114.                 arg[1],arg[2],arg[3],arg[4]);
  115.             if( brush_on )
  116.             {
  117.                 sync_input(infile);
  118.                 gdImageLine(img,arg[1],arg[2],arg[3],arg[4],gdBrushed);
  119.                 if (!quiet) fprintf(verbose_out,"colour = current brush");
  120.             }
  121.             else if ( style_on )
  122.             {
  123.                 sync_input(infile);
  124.                 gdImageLine(img,arg[1],arg[2],arg[3],arg[4],gdStyled);
  125.                 if (!quiet) fprintf(verbose_out,"colour = current style");
  126.             }
  127.             else
  128.             {
  129.                 colour=get_colour(infile,img);
  130.                 gdImageLine(img,arg[1],arg[2],arg[3],arg[4],colour);
  131.             }
  132.             if (!quiet) fprintf(verbose_out,")\n");
  133.             break;
  134.  
  135.  
  136.         case DLINE:     /*      gdImageDashedLine()     */
  137.             for(i=1;i<=4;i++){
  138.                 arg[i]=get_number(infile);
  139.             }
  140.             if (!quiet)
  141.                 fprintf(verbose_out,"## Dashed Line ## drawn from %d,%d to %d,%d. (",
  142.                 arg[1],arg[2],arg[3],arg[4]);
  143.             if( brush_on ){
  144.                 sync_input(infile);
  145.                 gdImageDashedLine(img,arg[1],arg[2],arg[3],arg[4],gdBrushed);
  146.                 if (!quiet) fprintf(verbose_out,"colour = current brush");
  147.             } else if ( style_on ) {
  148.                 sync_input(infile);
  149.                 gdImageDashedLine(img,arg[1],arg[2],arg[3],arg[4],gdStyled);
  150.                 if (!quiet) fprintf(verbose_out,"colour = current style");
  151.             } else{
  152.                 colour=get_colour(infile,img);
  153.                 gdImageDashedLine(img,arg[1],arg[2],arg[3],arg[4],colour);
  154.             }
  155.             if (!quiet) fprintf(verbose_out,")\n");
  156.             break;
  157.  
  158.         case SQUARE:      /*      gdImageRectangle()      */
  159.             for(i=1;i<=3;i++){
  160.                 arg[i]=get_number(infile);
  161.             }
  162.             side = arg[3];
  163.             arg[3] = arg[1] + side; arg[4] = arg[2] + side;
  164.             if (!quiet) fprintf(verbose_out,"## Square ## drawn at %d,%d, side %d (",
  165.                 arg[1],arg[2],side);
  166.             if( brush_on ){
  167.                 sync_input(infile);
  168.                 gdImageRectangle(img,arg[1],arg[2],arg[3],arg[4],gdBrushed);
  169.                 if (!quiet) fprintf(verbose_out,"colour = current brush");
  170.             } else if ( style_on ) {
  171.                 sync_input(infile);
  172.                 gdImageRectangle(img,arg[1],arg[2],arg[3],arg[4],gdStyled);
  173.                 if (!quiet) fprintf(verbose_out,"colour = current style");
  174.             } else{
  175.                 colour=get_colour(infile,img);
  176.                 gdImageRectangle(img,arg[1],arg[2],arg[3],arg[4],colour);
  177.             }
  178.             if (!quiet) fprintf(verbose_out,")\n");
  179.             break;
  180.  
  181.         case FSQUARE:     /*      gdImageFilledRectangle() */
  182.             for(i=1;i<=3;i++){
  183.                 arg[i]=get_number(infile);
  184.             }
  185.             side = arg[3];
  186.             arg[3] = arg[1] + side; arg[4] = arg[2] + side;
  187.             if (!quiet)
  188.                 fprintf(verbose_out,"## Filled Square ## drawn from %d,%d, side %d. (",
  189.                 arg[1],arg[2],side);
  190.             if( tile_on ){
  191.                 sync_input(infile);
  192.                 gdImageFilledRectangle(img,arg[1],arg[2],arg[3],arg[4],gdTiled);
  193.                 if (!quiet) fprintf(verbose_out,"colour = current tile");
  194.             } else{
  195.                 colour=get_colour(infile,img);
  196.                 gdImageFilledRectangle(img,arg[1],arg[2],arg[3],arg[4],colour);
  197.             }
  198.             if (!quiet) fprintf(verbose_out,")\n");
  199.             break;
  200.  
  201.         case RECT:      /*      gdImageRectangle()      */
  202.             for(i=1;i<=4;i++){
  203.                 arg[i]=get_number(infile);
  204.             }
  205.             if (!quiet) fprintf(verbose_out,"## Rectangle ## drawn from %d,%d to %d,%d. (",
  206.                 arg[1],arg[2],arg[3],arg[4]);
  207.             if( brush_on ){
  208.                 sync_input(infile);
  209.                 gdImageRectangle(img,arg[1],arg[2],arg[3],arg[4],gdBrushed);
  210.                 if (!quiet) fprintf(verbose_out,"colour = current brush");
  211.             } else if ( style_on ) {
  212.                 sync_input(infile);
  213.                 gdImageRectangle(img,arg[1],arg[2],arg[3],arg[4],gdStyled);
  214.                 if (!quiet) fprintf(verbose_out,"colour = current style");
  215.             } else{
  216.                 colour=get_colour(infile,img);
  217.                 gdImageRectangle(img,arg[1],arg[2],arg[3],arg[4],colour);
  218.             }
  219.             if (!quiet) fprintf(verbose_out,")\n");
  220.             break;
  221.  
  222.         case FRECT:     /*      gdImageFilledRectangle() */
  223.             for(i=1;i<=4;i++){
  224.                 arg[i]=get_number(infile);
  225.             }
  226.             if (!quiet)
  227.                 fprintf(verbose_out,"## Filled Rectangle ## drawn from %d,%d to %d,%d. (",
  228.                 arg[1],arg[2],arg[3],arg[4]);
  229.             if( tile_on ){
  230.                 sync_input(infile);
  231.                 gdImageFilledRectangle(img,arg[1],arg[2],arg[3],arg[4],gdTiled);
  232.                 if (!quiet) fprintf(verbose_out,"colour = current tile");
  233.             } else{
  234.                 colour=get_colour(infile,img);
  235.                 gdImageFilledRectangle(img,arg[1],arg[2],arg[3],arg[4],colour);
  236.             }
  237.             if (!quiet) fprintf(verbose_out,")\n");
  238.             break;
  239.  
  240.         case POLY:      /* gdImagePolygon() */
  241.             done = FALSE; i=0;
  242.  
  243.             if (!quiet) fprintf(verbose_out,"## Polygon ## (");
  244.             colour=get_colour(infile,img);
  245.             if (!quiet) fprintf(verbose_out,") ");
  246.  
  247.             arg[i++] = get_number(infile); /* get first point */
  248.             arg[i++] = get_number(infile);
  249.  
  250.             while( ! done ){     /* get next point until EOL*/
  251.                 for(c=0; c<=1 ;c++){
  252.                     arg[i++]=get_number(infile);
  253.                 }
  254.                 if (!quiet) fprintf(verbose_out,"%d,%d to %d,%d; ",
  255.                     arg[i-4],arg[i-3],arg[i-2],arg[i -1]);
  256.             }
  257.  
  258.             num_entries = i / 2;  i=0;
  259.             for(n=0; n<num_entries; n++)
  260.             {
  261.                 points[n].x = arg[i++];
  262.                 points[n].y = arg[i++];
  263.             }
  264.             if( brush_on ) {
  265.                 gdImagePolygon(img, points, num_entries, gdBrushed);
  266.             } else if ( style_on ) {
  267.                 gdImagePolygon(img, points, num_entries, gdStyled);
  268.             } else {
  269.                 gdImagePolygon(img, points, num_entries, colour);
  270.             }
  271.  
  272.             done = FALSE;
  273.             if (!quiet) fprintf(verbose_out,"\n");
  274.             break;
  275.  
  276.         case FPOLY:      /* gdImageFilledPolygon() */
  277.             done = FALSE; i=0;
  278.  
  279.             if (!quiet) fprintf(verbose_out,"## Filled Polygon ## (");
  280.             colour=get_colour(infile,img);
  281.             if (!quiet) fprintf(verbose_out,") ");
  282.  
  283.             arg[i++] = get_number(infile); /* get first point */
  284.             arg[i++] = get_number(infile);
  285.  
  286.             while( ! done ){     /* get next point until EOL*/
  287.                 for(c=0; c<=1 ;c++){
  288.                     arg[i++]=get_number(infile);
  289.                 }
  290.                 if (!quiet) fprintf(verbose_out,"%d,%d to %d,%d; ",
  291.                     arg[i-4],arg[i-3],arg[i-2],arg[i -1]);
  292.             }
  293.  
  294.             num_entries = i / 2;  i=0;
  295.             for(n=0; n<num_entries; n++)
  296.             {
  297.                 points[n].x = arg[i++];
  298.                 points[n].y = arg[i++];
  299.             }
  300.  
  301.             if( tile_on )
  302.             {
  303.                 gdImageFilledPolygon(img, points, num_entries, gdTiled);
  304.             }
  305.             else
  306.             {
  307.                 gdImageFilledPolygon(img, points, num_entries, colour);
  308.             }
  309.             done = FALSE;
  310.             if (!quiet) fprintf(verbose_out,"\n");
  311.             break;
  312.  
  313.         case ARC:       /*      gdImageArc()            */
  314.             for(i=1;i<7;i++){
  315.                 arg[i]=get_number(infile);
  316.             }
  317.             if (!quiet) {
  318.                 fprintf(verbose_out,"## Arc ## Centred at %d,%d, width %d, height %d,\n",
  319.                     arg[1],arg[2],arg[3],arg[4]);
  320.                 fprintf(verbose_out,"          starting at %d deg, ending at %d deg. (",
  321.                     arg[5],arg[6]);
  322.             }
  323.             if( brush_on ){
  324.             sync_input(infile);
  325.             gdImageArc(img,arg[1],arg[2],arg[3],arg[4],arg[5],arg[6],gdBrushed);
  326.             if(!quiet) fprintf(verbose_out,"colour = current brush");
  327.             } else if ( style_on ) {
  328.             sync_input(infile);
  329.             gdImageArc(img,arg[1],arg[2],arg[3],arg[4],arg[5],arg[6],gdStyled);
  330.             if(!quiet) fprintf(verbose_out,"colour = current style");
  331.             } else{
  332.             colour=get_colour(infile,img);
  333.             gdImageArc(img,arg[1],arg[2],arg[3],arg[4],arg[5],arg[6],colour);
  334.             }
  335.             if (!quiet) fprintf(verbose_out,")\n");
  336.             break;
  337.  
  338.         case CIRCLE:
  339.         case FCIRCLE:
  340.             for(i=1;i<4;i++){
  341.                 arg[i]=get_number(infile);
  342.             }
  343.             if (!quiet) {
  344.                 if (type == CIRCLE) {
  345.                     fprintf(verbose_out,"## Circle ## Centred at %d,%d, diameter %d (",
  346.                         arg[1],arg[2],arg[3]);
  347.                 }
  348.                 else {
  349.                     fprintf(verbose_out,"## Filled Circle ## Centred at %d,%d, diameter %d (",
  350.                         arg[1],arg[2],arg[3]);
  351.                 }
  352.             }
  353.             if( brush_on ){
  354.             sync_input(infile);
  355.             gdImageArc(img,arg[1],arg[2],arg[3],arg[3],0,360,gdBrushed);
  356.             if(!quiet) fprintf(verbose_out,"colour = current brush");
  357.             } else if ( style_on ) {
  358.             sync_input(infile);
  359.             gdImageArc(img,arg[1],arg[2],arg[3],arg[3],0,360,gdStyled);
  360.             if(!quiet) fprintf(verbose_out,"colour = current style");
  361.             } else{
  362.             colour=get_colour(infile,img);
  363.             gdImageArc(img,arg[1],arg[2],arg[3],arg[3],0,360,colour);
  364.             }
  365.             if (type == FCIRCLE) gdImageFillToBorder(img,arg[1],arg[2],colour,colour);
  366.             if (!quiet) fprintf(verbose_out,")\n");
  367.             break;
  368.  
  369.  
  370.         case SETPIXEL:      /*    gdImageSetPixel  */
  371.             for(i=1;i<=2;i++){
  372.                 arg[i]=get_number(infile);
  373.             }
  374.             if (!quiet) fprintf(verbose_out,"## Set Pixel ## at %d,%d to ",arg[1],arg[2]);
  375.             colour=get_colour(infile,img);
  376.             gdImageSetPixel(img,arg[1],arg[2],colour);
  377.             if (!quiet) fprintf(verbose_out,".\n");
  378.             break;
  379.  
  380.         case GETPIXEL:      /*    gdImageGetPixel  */
  381.             for(i=1;i<=2;i++){
  382.                 arg[i]=get_number(infile);
  383.             }
  384.             if (!quiet) fprintf(verbose_out,"## Get Pixel ## at %d,%d:",arg[1],arg[2]);
  385.             colour = gdImageGetPixel(img,arg[1],arg[2]);
  386.             arg[3] = gdImageRed(img,colour);
  387.             arg[4] = gdImageGreen(img,colour);
  388.             arg[5] = gdImageBlue(img,colour);
  389.             if (!quiet) fprintf(verbose_out," %d, %d, %d = %d.\n",
  390.                 arg[3],arg[4],arg[5],colour);
  391.             break;
  392.  
  393.         case FILL:      /*      gdImageFill() */
  394.             for(i=1;i<=2;i++){
  395.                 arg[i]=get_number(infile);
  396.             }
  397.             if (!quiet) fprintf(verbose_out,"## Fill ## from %d,%d. (", arg[1],arg[2]);
  398.             if( tile_on ){
  399.                 sync_input(infile);
  400.                 gdImageFill(img,arg[1],arg[2],gdTiled);
  401.             } else {
  402.                 colour=get_colour(infile,img);
  403.                 gdImageFill(img,arg[1],arg[2],colour);
  404.             }
  405.             if (!quiet) fprintf(verbose_out,")\n");
  406.             break;
  407.  
  408.         case FILLTOBORDER:      /*    gdImageFillToBorder()    */
  409.             for(i=1;i<=2;i++){
  410.                 arg[i]=get_number(infile);
  411.             }
  412.             if (!quiet) fprintf(verbose_out,"## Fill ## from %d,%d. (", arg[1],arg[2]);
  413.             colour=get_colour(infile,img);
  414.             if (!quiet) fprintf(verbose_out,") to Border of ");
  415.             if( tile_on ){
  416.                 sync_input(infile);
  417.                 gdImageFillToBorder(img,arg[1],arg[2],colour,gdTiled);
  418.             } else {
  419.                 colour2=get_colour(infile,img);
  420.                 gdImageFillToBorder(img,arg[1],arg[2],colour,colour2);
  421.             }
  422.             if (!quiet) fprintf(verbose_out,".\n");
  423.             break;
  424.  
  425.         case STRINGUP:
  426.             up = TRUE;
  427.         case STRING:
  428.             if (!quiet && up) fprintf(verbose_out,"## String (Up) ## (");
  429.             if (!quiet && !up) fprintf(verbose_out,"## String ## (");
  430.             colour=get_colour(infile,img);
  431.             if (!quiet) fprintf(verbose_out,") at location ");
  432.             for(i=1;i<=2;i++){
  433.                 arg[i]=get_number(infile);
  434.             }
  435.             if (!quiet) fprintf(verbose_out," %d,%d, ",arg[1],arg[2]);
  436.             i=get_token(infile);
  437.             switch(i)
  438.             {
  439.             case TINY:
  440.                 s = get_string(infile);
  441.                 if (!quiet) fprintf(verbose_out,"[size: tiny] contents: %s\n",s);
  442.                 if( !up ) {
  443.                 gdImageString(img, gdFontTiny, arg[1],arg[2], s, colour);
  444.                 } else {
  445.                 gdImageStringUp(img, gdFontTiny, arg[1],arg[2], s, colour);
  446.                 }
  447.                 break;
  448.             case SMALL:
  449.                 s = get_string(infile);
  450.                 if (!quiet) fprintf(verbose_out,"[size: small] contents: %s\n",s);
  451.                 if( !up ) {
  452.                 gdImageString(img, gdFontSmall, arg[1],arg[2], s, colour);
  453.                 } else {
  454.                 gdImageStringUp(img, gdFontSmall, arg[1],arg[2], s, colour);
  455.                 }
  456.                 break;
  457.             case MEDIUM:
  458.                 s = get_string(infile);
  459.                 if (!quiet) fprintf(verbose_out,"[size: medium-bold] contents: %s\n",s);
  460.                 if( !up ) {
  461.                 gdImageString(img,gdFontMediumBold, arg[1],arg[2],s,colour);
  462.                 } else {
  463.                 gdImageStringUp(img,gdFontMediumBold,arg[1],arg[2],s,colour);
  464.                 }
  465.                 break;
  466.             case LARGE:
  467.                 s = get_string(infile);
  468.                 if (!quiet) fprintf(verbose_out,"[size: large] contents: %s\n",s);
  469.                 if( !up ) {
  470.                 gdImageString(img, gdFontLarge, arg[1],arg[2], s, colour);
  471.                 } else {
  472.                 gdImageStringUp(img, gdFontLarge, arg[1],arg[2], s, colour);
  473.                 }
  474.                 break;
  475.             case GIANT:
  476.                 s = get_string(infile);
  477.                 if (!quiet) fprintf(verbose_out,"[size: giant] contents: %s\n",s);
  478.                 if( !up ) {
  479.                 gdImageString(img, gdFontGiant, arg[1],arg[2], s, colour);
  480.                 } else {
  481.                 gdImageStringUp(img, gdFontGiant, arg[1],arg[2], s, colour);
  482.                 }
  483.                 break;
  484.             }
  485.             up = FALSE;
  486.             break;
  487.  
  488.         case SETBRUSH:
  489.             s = get_string(infile);
  490.             if ( (brushfile = fopen(s,"rb")) == NULL )
  491.             {
  492.                 fprintf(stderr, "Failed to open brush file, %s\n",
  493.                     output_file);
  494.                 exit(1);
  495.             }
  496.             else
  497.             {
  498.                 brush = gdImageCreateFromGif(brushfile);
  499.                 gdImageSetBrush(img,brush);
  500.                 brush_on = 1;
  501.                 if (!quiet) fprintf(verbose_out,"## Brush Set ## to: %s\n",s);
  502.             }
  503.             break;
  504.  
  505.         case KILLBRUSH:
  506.             brush_on = 0;
  507.             if (!quiet) fprintf(verbose_out,"## Brush Killed ##\n");
  508.             break;
  509.  
  510.         case SETSTYLE:
  511.             i=0;
  512.             end_of_line = FALSE;
  513.             if (!quiet) fprintf(verbose_out,"## Style Set ## Colours: (");
  514.             while( ! end_of_line ){
  515.                 colour=get_colour(infile,img);
  516.                 if (!quiet && !end_of_line) fprintf(verbose_out,"), (");
  517.                 style[i++] = colour;
  518.             }
  519.             if (!quiet) fprintf(verbose_out,")\n");
  520.             gdImageSetStyle(img, style, i-1);
  521.             style_on = TRUE;
  522.             end_of_line = FALSE;
  523.             break;
  524.  
  525.         case KILLSTYLE:
  526.             style_on = 0;
  527.             if (!quiet) fprintf(verbose_out,"## Style Killed ##\n");
  528.             break;
  529.  
  530.         case SETTILE:
  531.             s = get_string(infile);
  532.             if ( (tilefile = fopen(s,"rb")) == NULL )
  533.             {
  534.                 fprintf(stderr, "Failed to open tile file, %s\n",
  535.                     output_file);
  536.                 exit(1);
  537.             }
  538.             else
  539.             {
  540.                 tile = gdImageCreateFromGif(tilefile);
  541.                 gdImageSetTile(img,tile);
  542.                 tile_on = TRUE;
  543.                 if (!quiet) fprintf(verbose_out,"## Tile Set ## to: %s\n",s);
  544.             }
  545.             break;
  546.  
  547.         case KILLTILE:
  548.             tile_on = 0;
  549.             if (!quiet) fprintf(verbose_out,"## Tile Killed ##\n");
  550.             break;
  551.  
  552.         case COPY:
  553.             copy_to_gif(infile, img, 0);
  554.             break;
  555.  
  556.         case COPYRESIZED:
  557.             copy_to_gif(infile, img, 1);
  558.             break;
  559.  
  560.         case TRANSPARENT:
  561.             if (!quiet) fprintf(verbose_out,"## Make transparent ## [");
  562.             colour=get_colour(infile,img);
  563.             gdImageColorTransparent(img,colour);
  564.             if (!quiet) fprintf(verbose_out,"]\n");
  565.             break;
  566.  
  567.         case INTERLACE:
  568.             gdImageInterlace(img,1);
  569.             if (!quiet) fprintf(verbose_out,"## Image is interlaced ##\n");
  570.             break;
  571.  
  572.         case SIZEX:
  573.             size = gdImageSX(img);
  574.             if (!quiet) fprintf(verbose_out,"## Size - X ## is %d\n",size);
  575.             break;
  576.  
  577.         case SIZEY:
  578.             size = gdImageSY(img);
  579.             if (!quiet) fprintf(verbose_out,"## Size - Y ## is %d\n",size);
  580.             break;
  581.  
  582.         case NAME:
  583.             s = get_string(infile);
  584.             if ( (outfile = fopen(s,"wb")) == NULL )
  585.             {
  586.                 fprintf(stderr, "Failed to open output file, %s\n",
  587.                     output_file);
  588.                 exit(1);
  589.             }
  590.             else
  591.             {
  592.                 if (!quiet) fprintf(verbose_out,"## Output to file %s ##\n",s);
  593.             }
  594.             break;
  595.  
  596.         case COMMENT:
  597.             sync_input(infile);
  598.             break;
  599.  
  600.         case EMPTY:
  601.             break;
  602.  
  603.         case END:
  604.             gdImageGif(img,outfile);
  605.             fclose(outfile);
  606.             gdImageDestroy(img);
  607.             goto START;
  608.             
  609.         default:
  610.             if( ! finished )
  611.             {
  612.                 if (!quiet)
  613.                     fprintf(verbose_out,"Line %d skipped: bad directive or syntax error.\n",line_number);
  614.             }
  615.             else
  616.             {
  617.                 if (!quiet) fprintf(verbose_out,"EOF: fly finished.\n");
  618.             }
  619.             sync_input(infile);
  620.             break;
  621.         }
  622.     }    while( ! finished );
  623.  
  624.     /*  Write the gd to the GIF output file and exit */
  625.     gdImageGif(img,outfile);
  626.     fclose(outfile);
  627.     gdImageDestroy(img);
  628.     exit(0);
  629. }
  630.  
  631. /******************************************************************************
  632. **
  633. **  get_string
  634. **
  635. **  returns a string from the current input line: from the current point
  636. **  to the end of line.
  637. **
  638. **  Used by:
  639. **  string,stringup,chr,chrup,setbrush,settile
  640. **
  641. ******************************************************************************/
  642. char *get_string(FILE *infile){
  643.     int     c,i=0;
  644.     char    temp[1024], *string, *p;
  645.  
  646.     while(( (c=getc(infile)) != EOF ) && ( c != '\n') ){
  647.         temp[i++]=c;
  648.     }
  649.  
  650.     if( c == '\n' ) { line_number++; }
  651.     if( c == EOF ) {
  652.         finished = TRUE;
  653.     }
  654.     temp[i]='\0';
  655.     p=temp;
  656.     string=(char *)my_newmem(strlen(p));
  657.     sprintf(string,"%s",temp);
  658.  
  659.     return string;
  660. }
  661.  
  662. /******************************************************************************
  663. **
  664. **  get_token
  665. **
  666. **  Gets the next "token" from the input line.
  667. **
  668. **  Used by:
  669. **  all
  670. **
  671. ******************************************************************************/
  672. int get_token(FILE *infile){
  673.     int     c,i=0;
  674.     char    temp[80], *input_type, *p;
  675.     char    *line="line",
  676.         *poly="poly",
  677.         *fpoly="fpoly",
  678.         *rect="rect",
  679.         *frect="frect",
  680.         *square="square",
  681.         *fsquare="fsquare",
  682.         *dline="dline",
  683.         *arc="arc",
  684.         *size="size",
  685.         *new="new",
  686.         *existing="existing",
  687.         *setpixel="setpixel",
  688.         *getpixel="getpixel",
  689.         *filltoborder="filltoborder",
  690.         *fill="fill",
  691.         *string="string",
  692.         *stringup="stringup",
  693.         *copy="copy",
  694.         *copyresized="copyresized",
  695.         *transparent="transparent",
  696.         *interlace="interlace",
  697.         *sizex="sizex",
  698.         *sizey="sizey",
  699.         *setbrush="setbrush",
  700.         *killbrush="killbrush",
  701.         *settile="settile",
  702.         *killtile="killtile",
  703.         *setstyle="setstyle",
  704.         *killstyle="killstyle",
  705.         *tiny="tiny",
  706.         *small="small",
  707.         *medium="medium",
  708.         *large="large",
  709.         *giant="giant",
  710.         *zero="0",
  711.         *one="1",
  712.         *circle="circle",
  713.         *fcircle="fcircle",
  714.         *comment="#",
  715.         *name="name",
  716.         *end="end";
  717.  
  718.     while(((c=getc(infile))!=EOF)&&(c!=' ')&&(c!='\n')&&(c!=',')&&(c!='='))
  719.     {
  720.         temp[i++]=c;
  721.         if(temp[0] == '#') break;
  722.     }
  723.  
  724.     if( (c == '\n') && (i == 0) ) { line_number++;  return EMPTY; }
  725.  
  726.     if( c == EOF )
  727.     {
  728.         finished = TRUE;
  729.         return NULL;
  730.     }
  731.     temp[i]='\0';
  732.     p=temp;
  733.     input_type=(char*)my_newmem(strlen(p));
  734.     sprintf(input_type,"%s",temp);
  735.  
  736.     if( strcmp(input_type, line) == 0 ){
  737.         free(input_type);
  738.         return LINE;
  739.     }
  740.     if( strcmp(input_type, rect) == 0 ){
  741.         free(input_type);
  742.         return RECT;
  743.     }
  744.     if( strcmp(input_type, square) == 0 ){
  745.         free(input_type);
  746.         return SQUARE;
  747.     }
  748.     if( strcmp(input_type, fsquare) == 0 ){
  749.         free(input_type);
  750.         return FSQUARE;
  751.     }
  752.     if( strcmp(input_type, dline) == 0 ){
  753.         free(input_type);
  754.         return DLINE;
  755.     }
  756.     if( strcmp(input_type, frect) == 0 ){
  757.         free(input_type);
  758.         return FRECT;
  759.     }
  760.     if( strcmp(input_type, fcircle) == 0 ){
  761.         free(input_type);
  762.         return FCIRCLE;
  763.     }
  764.     if( strcmp(input_type, circle) == 0 ){
  765.         free(input_type);
  766.         return CIRCLE;
  767.     }
  768.     if( strcmp(input_type, arc) == 0 ){
  769.         free(input_type);
  770.         return ARC;
  771.     }
  772.     if( strcmp(input_type, poly) == 0 ){
  773.         free(input_type);
  774.         return POLY;
  775.     }
  776.     if( strcmp(input_type, fpoly) == 0 ){
  777.         free(input_type);
  778.         return FPOLY;
  779.     }
  780.     if( strcmp(input_type, size) == 0 ){
  781.         free(input_type);
  782.         return SIZE;
  783.     }
  784.     if( strcmp(input_type, new) == 0 ){
  785.         free(input_type);
  786.         return NEW;
  787.     }
  788.     if( strcmp(input_type, existing) == 0 ){
  789.         free(input_type);
  790.         return EXISTING;
  791.     }
  792.     if( strcmp(input_type, copyresized) == 0 ){
  793.         free(input_type);
  794.         return COPYRESIZED;
  795.     }
  796.     if( strcmp(input_type, copy) == 0 ){
  797.         free(input_type);
  798.         return COPY;
  799.     }
  800.     if( strcmp(input_type, fill) == 0 ){
  801.         free(input_type);
  802.         return FILL;
  803.     }
  804.     if( strcmp(input_type, filltoborder) == 0 ){
  805.         free(input_type);
  806.         return FILLTOBORDER;
  807.     }
  808.     if( strcmp(input_type, setpixel) == 0 ){
  809.         free(input_type);
  810.         return SETPIXEL;
  811.     }
  812.     if( strcmp(input_type, getpixel) == 0 ){
  813.         free(input_type);
  814.         return GETPIXEL;
  815.     }
  816.     if( strcmp(input_type, string) == 0 ){
  817.         free(input_type);
  818.         return STRING;
  819.     }
  820.     if( strcmp(input_type, stringup) == 0 ){
  821.         free(input_type);
  822.         return STRINGUP;
  823.     }
  824.     if( strcmp(input_type, sizex) == 0 ){
  825.         free(input_type);
  826.         return SIZEX;
  827.     }
  828.     if( strcmp(input_type, sizey) == 0 ){
  829.         free(input_type);
  830.         return SIZEY;
  831.     }
  832.     if( strcmp(input_type, setbrush) == 0 ){
  833.         free(input_type);
  834.         return SETBRUSH;
  835.     }
  836.     if( strcmp(input_type, killbrush) == 0 ){
  837.         free(input_type);
  838.         return KILLBRUSH;
  839.     }
  840.     if( strcmp(input_type, settile) == 0 ){
  841.         free(input_type);
  842.         return SETTILE;
  843.     }
  844.     if( strcmp(input_type, killtile) == 0 ){
  845.         free(input_type);
  846.         return KILLTILE;
  847.     }
  848.     if( strcmp(input_type, setstyle) == 0 ){
  849.         free(input_type);
  850.         return SETSTYLE;
  851.     }
  852.     if( strcmp(input_type, killstyle) == 0 ){
  853.         free(input_type);
  854.         return KILLSTYLE;
  855.     }
  856.     if( strcmp(input_type, interlace) == 0 ){
  857.         free(input_type);
  858.         return INTERLACE;
  859.     }
  860.     if( strcmp(input_type, transparent) == 0 ){
  861.         free(input_type);
  862.         return TRANSPARENT;
  863.     }
  864.     if( strcmp(input_type, tiny) == 0 ){
  865.         free(input_type);
  866.         return TINY;
  867.     }
  868.     if( strcmp(input_type, zero) == 0 ){
  869.         free(input_type);
  870.         return SMALL;
  871.     }
  872.     if( strcmp(input_type, small) == 0 ){
  873.         free(input_type);
  874.         return SMALL;
  875.     }
  876.     if( strcmp(input_type, medium) == 0 ){
  877.         free(input_type);
  878.         return MEDIUM;
  879.     }
  880.     if( strcmp(input_type, one) == 0 ){
  881.         free(input_type);
  882.         return LARGE;
  883.     }
  884.     if( strcmp(input_type, large) == 0 ){
  885.         free(input_type);
  886.         return LARGE;
  887.     }
  888.     if( strcmp(input_type, giant) == 0 ){
  889.         free(input_type);
  890.         return GIANT;
  891.     }
  892.     if( strcmp(input_type, name) == 0){
  893.         free(input_type);
  894.         return NAME;
  895.     }
  896.     if( strcmp(input_type, comment) == 0){
  897.         free(input_type);
  898.         return COMMENT;
  899.     }
  900.     if( strcmp(input_type, end) == 0){
  901.         free(input_type);
  902.         return END;
  903.     }
  904.     free(input_type);
  905.     ungetc(c,infile);
  906.     return NULL;
  907. }
  908.  
  909. /******************************************************************************
  910. **
  911. **  get_number
  912. **
  913. **  grabs a number from the current input line. Reads up to a comma or newline.
  914. **
  915. **  Used by:
  916. **  line, dline, rect, frect, poly, fpoly, arc, setpixel, fill, filltoborder,
  917. **  string, stringup, chr, chrup.
  918. **
  919. ******************************************************************************/
  920. int get_number(FILE *infile){
  921.     int     c,i=0;
  922.     char    tmp[80];
  923.  
  924.     while(( (c=getc(infile)) != EOF ) && ( c != ',') && (c != '\n')){
  925.         tmp[i++]=c;
  926.     }
  927.     if( c == '\n' ) { line_number++; }
  928.     if( c != EOF ) {
  929.         tmp[i]='\0';
  930.         if( c == '\n') {
  931.             done = TRUE;
  932.         }
  933.         return atoi(tmp);
  934.     }
  935.     else {
  936.         tmp[i]='\0';
  937.         finished = TRUE;
  938.         return atoi(tmp);
  939.     }
  940.     return NULL;
  941. }
  942.  
  943. /******************************************************************************
  944. **
  945. **  get_colour
  946. **
  947. **  Gets a R,G,B colour value from the current input line.
  948. **  Returns the integer colour index.
  949. **
  950. **  Used by:
  951. **  line, dline, rect, frect, poly, fpoly, arc, setpixel, fill, filltoborder,
  952. **  string, stringup, chr, chrup, setstyle, transparent.
  953. **
  954. ******************************************************************************/
  955. int get_colour(FILE *infile, gdImagePtr img){
  956.     int     c,i,count,colourIndex, colour[3];
  957.     char    temp[5];
  958.  
  959.     for(count=0;count<3;count++){
  960.         i=0;
  961.         while(( (c=getc(infile)) != EOF )&&( c !=',')&&(c !='\n')){
  962.             temp[i++]=c;
  963.         }
  964.         if( c == '\n' ) { line_number++; }
  965.         temp[i]='\0';
  966.         if( c == '\n') end_of_line = TRUE;
  967.         if( c == EOF ) finished = TRUE;
  968.         colour[count]=atoi(temp);
  969.     }
  970.     if( (c=getc(infile)) != EOF )  { 
  971.         ungetc(c,infile); 
  972.     }
  973.     else { 
  974.         finished = TRUE; 
  975.     }
  976.     /* Original comments from Claus Hofmann. I don't have any idea what they
  977.          * mean, but I'll put 'em here anyhow.
  978.      */
  979.     /* zuerst nachschauen, ob es die gewuenschte Farbe schon in der 
  980.      * colortable gibt. Erst wenn es die Farbe nicht gibt einen neuen
  981.      * Index in der Tabelle allocieren.
  982.      */
  983.     colourIndex=gdImageColorExact(img,colour[0],colour[1],colour[2]);
  984.     if (-1 == colourIndex) {
  985.         colourIndex=gdImageColorAllocate(img,colour[0],colour[1],colour[2]);
  986.     }
  987.     if (!quiet)
  988.         fprintf(verbose_out,"colour: %d, %d, %d = %d",
  989.             colour[0],colour[1],colour[2], colourIndex);
  990.     return colourIndex;
  991.  
  992. }
  993.  
  994. /******************************************************************************
  995. **
  996. **  copy_to_gif
  997. **
  998. **  Copies a gif to the current image. Location of gif and coordinates are
  999. **  specified on the input line.
  1000. **
  1001. **  Used by:
  1002. **  copy, copyresized.
  1003. **
  1004. ******************************************************************************/
  1005. void copy_to_gif(FILE *infile, gdImagePtr img, int resize){
  1006.     int     c,i=0,arg[8];
  1007.     char    temp[1256], *filename;
  1008.     FILE    *img_to_copy;
  1009.     gdImagePtr    img_file;
  1010.  
  1011.     /*    Get the coordinates    */
  1012.     for(i=0;i<=5;i++){
  1013.         arg[i]=get_number(infile);
  1014.     }
  1015.     if( resize == 1 ){
  1016.         arg[i]=get_number(infile);
  1017.         i++;
  1018.         arg[i]=get_number(infile);
  1019.     }
  1020.     i=0;
  1021.     /*    Get the filename    */
  1022.     while(( (c=getc(infile)) != EOF ) && ( c != ' ') && ( c != '\n') ){
  1023.         temp[i++]=c;
  1024.     }
  1025.     if( c == '\n' ) { line_number++; }
  1026.     temp[i]='\0';
  1027.     filename=(char*)my_newmem(i * sizeof(char));
  1028.     sprintf(filename,"%s",temp);
  1029.     
  1030.     if(!quiet) fprintf(verbose_out,"Copying GIF from existing file: %s\n",filename);
  1031.  
  1032.     if( (img_to_copy = fopen(filename, "rb")) == NULL ) {
  1033.         fprintf(stderr,"Error: Cannot read existing GIF file \"%s\"\n",
  1034.             filename);
  1035.         exit(0);
  1036.     }
  1037.     img_file = gdImageCreateFromGif(img_to_copy);
  1038.     fclose(img_to_copy);
  1039.  
  1040.     if ((arg[2] == -1)&&(arg[3] == -1) &(arg[4] == -1)&&(arg[5] == -1)) {
  1041.             /* another comment from Claus Hofmann. I'm getting curious now. */
  1042.             /* gesamtes Bild 
  1043.             */
  1044.         arg[2] = arg[3] = 0;
  1045.         arg[4] = img_file->sx;
  1046.         arg[5] = img_file->sy;
  1047.     }
  1048.     if( resize == 1 )
  1049.     {
  1050.         if(!quiet) fprintf(verbose_out,"Copying %s (area %d,%d - %d,%d) to area %d,%d - %d,%d.\n",
  1051.             filename,arg[4],arg[5],arg[6], arg[7],arg[0],arg[1],arg[2],arg[3]);
  1052.         gdImageCopyResized(img, img_file, arg[4], arg[5], arg[0], arg[1],
  1053.             (arg[6] - arg[4]), (arg[7] - arg[5]), (arg[2] - arg[0]),
  1054.             (arg[3] - arg[1]));
  1055.     }
  1056.     else
  1057.     {
  1058.         if(!quiet) fprintf(verbose_out,"Copying %s to coordinates %d,%d\n",filename,arg[0],arg[1]);
  1059.         gdImageCopy(img, img_file, arg[0], arg[1], arg[2], arg[3],
  1060.                     arg[4] - arg[2], arg[5] - arg[3]);
  1061.     }
  1062.     gdImageDestroy(img_file);
  1063.  
  1064.     return;
  1065. }
  1066.  
  1067. /******************************************************************************
  1068. **
  1069. **  sync_input
  1070. **
  1071. **  synchronises input line - reads to end of line, leaving file pointer
  1072. **  at first character of next line.
  1073. **
  1074. **  Used by:
  1075. **  main program - error handling.
  1076. **
  1077. ******************************************************************************/
  1078. void
  1079. sync_input(FILE *infile)
  1080. {
  1081.     int c;
  1082.  
  1083.     if( c == '\n' ) return;
  1084.     while( ( (c=getc(infile)) != EOF ) && (c != '\n') ) ;
  1085.     if( c == EOF ) finished = TRUE;
  1086.     if( c == '\n' ) line_number++;
  1087.     return;
  1088. }
  1089.  
  1090. /******************************************************************************
  1091. **
  1092. **  process_args
  1093. **
  1094. **  processes the command line arguments
  1095. **
  1096. **  Used by:
  1097. **  main program.
  1098. **
  1099. ******************************************************************************/
  1100. int
  1101. process_args(int argc, char *argv[])
  1102. {
  1103.     char *check;
  1104.     int c, errflag=0;
  1105.     extern char *optarg;
  1106.     extern int optind;
  1107.  
  1108.     /* if( (check=strstr(argv[0],"flycgi")) != NULL ) 
  1109.     {
  1110.         quiet = TRUE;
  1111.         fprintf(stdout,"Content-type: image/gif\n\n");
  1112.     } */
  1113.  
  1114.     while ((c=getopt(argc, argv, "qhvi:o:")) != EOF)
  1115.     {
  1116.         switch (c) {
  1117.             case 'q': quiet = TRUE;
  1118.                     break;
  1119.             case 'v':
  1120.             case 'h': fprintf(stdout,"fly, version %s\n\n%s\n", version, help);
  1121.                       exit(0);
  1122.                     break;
  1123.             case 'o': output_file=(char *)my_newmem(strlen(optarg)*sizeof(char));
  1124.                       sprintf(output_file,"%s",optarg);
  1125.                     break;
  1126.             case 'i': input_file=(char *)my_newmem(strlen(optarg)*sizeof(char));
  1127.                       sprintf(input_file,"%s",optarg);
  1128.                     break;
  1129.             case '?': errflag = 1;
  1130.                     break;
  1131.         }
  1132.         if (errflag)
  1133.         {
  1134.             fprintf(stderr,"%s\n", usage);
  1135.             exit(1);
  1136.         }
  1137.     }
  1138.     if( input_file )
  1139.     {
  1140.         if ( (infile = fopen(input_file,"r")) == NULL )
  1141.         {
  1142.             fprintf(stderr, "Failed to open input file, %s.\n",
  1143.                 input_file);
  1144.             return FALSE;
  1145.         }
  1146.     }
  1147.     else
  1148.     {
  1149.         infile = stdin;
  1150.     }
  1151.     if( output_file )
  1152.     {
  1153.         if ( (outfile = fopen(output_file,"wb")) == NULL )
  1154.         {
  1155.             fprintf(stderr, "Failed to open output file, %s.\n",
  1156.                 output_file);
  1157.             return FALSE;
  1158.         }
  1159.         verbose_out = stdout;
  1160.     }
  1161.     else
  1162.     {
  1163.         outfile = stdout;
  1164.         verbose_out = stderr;
  1165.     }
  1166.     return TRUE;
  1167. }
  1168.  
  1169. /******************************************************************************
  1170. **
  1171. **  get_image
  1172. **
  1173. **  creates a new image or uses an existing one as a template.
  1174. **
  1175. **  Used by:
  1176. **  main program
  1177. **
  1178. ******************************************************************************/
  1179. gdImagePtr get_image(int type, int argc, char *argv[]){
  1180.     FILE *in;
  1181.     int n=0, ch, num[10];
  1182.     char fname[1256], *filename;
  1183.     gdImagePtr image;
  1184.     int newtype;
  1185.  
  1186.     if( type == EXISTING ) {
  1187.         /*     fprintf(stderr,"Creating GIF from existing file:"); */
  1188.         while(( (ch=getc(infile)) != EOF ) && ( ch != ' ') && ( ch != '\n')){
  1189.             fname[n++]=ch;
  1190.         }
  1191.         if( ch == '\n' ) { line_number++; }
  1192.         fname[n]='\0';
  1193.         filename = (char *) my_newmem( n );
  1194.         sprintf(filename,"%s",fname);
  1195.         /*  fprintf(stderr," %s\n",filename); */
  1196.         if( (in = fopen(filename, "rb")) == NULL ) {
  1197.             fprintf(stderr,"Error: Cannot read existing GIF file \"%s\"\n",
  1198.                 filename);
  1199.             exit(0);
  1200.         }
  1201.         else {
  1202.             if(!quiet) fprintf(verbose_out,"Creating image from existing gif <%s>\n",
  1203.                 filename);
  1204.             image = gdImageCreateFromGif(in);
  1205.             fclose(in);
  1206.         }
  1207.     }
  1208.     else if( type == NEW ){
  1209.         newtype = get_token(infile);
  1210.         while( (newtype == COMMENT) || (newtype == EMPTY) || (newtype != SIZE) )
  1211.         {
  1212.             sync_input(infile);
  1213.             newtype = get_token(infile);
  1214.         }
  1215.         if( newtype != SIZE ) {
  1216.             if( argc == 2){
  1217.                 fprintf(stderr,"Error: <stdin> second line ");
  1218.                 fprintf(stderr,"must have a 'size' command\n");
  1219.             }
  1220.             else{
  1221.                 fprintf(stderr,"Error: %s second line must ");
  1222.                 fprintf(stderr,"have a 'size' command\n",argv[1]);
  1223.             }
  1224.             exit(0);
  1225.         }
  1226.         for( n=1; n<=2; n++ ){
  1227.             num[n]=get_number(infile);
  1228.         }
  1229.         if (!quiet)
  1230.         {
  1231.             if( output_file )
  1232.             {
  1233.                 fprintf(verbose_out,"Creating new %d by %d gif, <%s>\n",
  1234.                     num[1],num[2],output_file);
  1235.             }
  1236.             else
  1237.             {
  1238.                 fprintf(verbose_out,"Creating new %d by %d gif\n",
  1239.                     num[1],num[2]);
  1240.             }
  1241.         }
  1242.         image = gdImageCreate(num[1],num[2]);
  1243.     }
  1244.     return image;
  1245. }
  1246.  
  1247. /******************************************************************************
  1248. **
  1249. **  my_newmem: grab some memory.
  1250. **
  1251. **  -  Concentrates memory error handling in one place.
  1252. **
  1253. **
  1254. **  Used by:
  1255. **  string,stringup,chr,chrup,setbrush,settile
  1256. **
  1257. ******************************************************************************/
  1258. void *
  1259. my_newmem(size_t size)
  1260. {
  1261.     void    *p;
  1262.  
  1263.     if ((p = malloc(size +1)) == NULL)
  1264.     {
  1265.         fprintf(stderr, "fly: ran out of memory\n");
  1266.         exit(1);
  1267.     }
  1268.  
  1269.     return p;
  1270. }
  1271.  
  1272. /******************************************************************************/
  1273.